package cn.script.fxj.bind;

import cn.script.fxj.bind.utils.BindPropertyUtils;
import cn.script.fxj.bind.utils.BindRectField;
import javafx.beans.property.Property;
import jdk.nashorn.internal.ir.annotations.Ignore;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class BindOpt {

    private Object bindObj;

    private List<String> allBind;


    public BindOpt(Object bindObj, String[] allBind) {
        this.bindObj = bindObj;
        this.setField(allBind);
    }

    private void setField(String[] allBind) {
        this.check();
        this.allBind = new ArrayList<String>(Arrays.asList(allBind));
    }


    private void check() {
        if (this.bindObj == null) {
            throw new RuntimeException("绑定对象不能为空");
        }
    }


    private Property getComPeo(String instruction) {
        String[] split = instruction.split("\\.");
        if (split.length != 2) {
            throw new RuntimeException("指令命令错误");
        }
        Object beanField = BindRectField.getBeanField(this.bindObj, split[0]);
        if (beanField == null) {
            throw new RuntimeException(split[0] + "组件获取失败");
        }
        String comInst = split[1] + "Property";
        try {
            Method method = beanField.getClass().getMethod(comInst);
            if (method == null) {
                throw new RuntimeException(comInst + "方法不存在");
            }
            return (Property) method.invoke(beanField);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 绑定操作
     */
    public void bind(Map<String, Property> allMap, Class tClass, Object obj) throws Exception {
        for (String toFx : this.allBind) {
            String[] split = toFx.split("=");
            Field field = tClass.getDeclaredField(split[0]);
            if (field == null) {
                throw new RuntimeException("--" + split[0] + "--字段不存在");
            }
            Ignore annotation = field.getAnnotation(Ignore.class);
            if (annotation != null) {
                throw new RuntimeException("--" + split[0] + "--获取不到;请确认");
            }
            Property property = BindPropertyUtils.getProperty(field.getType());
            if (property == null) {
                throw new RuntimeException(split[0] + "=> 此字段类型不支持绑定");
            }
            allMap.put(split[0], property);
            Object value = BindRectField.getBeanField(obj, split[0]);
            if (value != null) {
                property.setValue(value);
            }
            Property comPeo = this.getComPeo(split[1]);
            comPeo.bindBidirectional(property);
        }
    }
}
